#include <iostream>
using std::cout;
using std::endl;
//单例对象放置在堆区
class Singleton{
public:
#if 0
    如果像之前一样在外部操作该对象，编写方式
    void func(){
        Singleton * _pInstance = new Singleton();
        delete _pInstance;
        _pInstance = nullptr;
    }
#endif

    static Singleton * getInstance(){
        if(_pInstance == nullptr){
            //没有创建过对象
            _pInstance = new Singleton();
        }
        return _pInstance;
    }
    static void destroy(){
        if(_pInstance){
            delete _pInstance;
            _pInstance = nullptr;
        }
    }
    void print(){
        cout << "Singleton::print" << endl;
    }

    Singleton(const Singleton & rhs) = delete;
    Singleton & operator=(const Singleton & rhs) = delete;

    //析构函数的主要作用是什么？？？回收该对象的数据成员申请的
    //堆空间
private:
    Singleton(){

    }
    ~Singleton(){
    }

    static Singleton * _pInstance;
};
//返回结果类型 类名::变量名称 = xxx
Singleton * Singleton::_pInstance = nullptr;


void test(){
    Singleton * ps1 = Singleton::getInstance();
    Singleton * ps2 = Singleton::getInstance();
    cout << ps1 << ":" << ps2 << endl;
    //考虑到外部使用者可能会使用多个指针来指向单例对象
    //删除的时候，可能不删除，也可能是都执行了delete删除操作
    //会出现double free的情况
    //所以稳妥起见，不让外部程序能够调用delete
    //自己封装一个函数来处理，无管该函数调用多少次，那么结果
    //始终是一致的
    //delete ps1;
    //delete ps2;
    Singleton::destroy();
    Singleton::destroy();
}

void test2(){
    //对于创建在堆区的单例对象使用的话，其实玩不需要用一个
    //指针变量来接收
    Singleton::getInstance()->print();
    Singleton::destroy();
}

int main()
{
    test2();
    return 0;
}

